home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / time / Time_ToParts.c < prev    next >
C/C++ Source or Header  |  1990-09-11  |  6KB  |  253 lines

  1. /* 
  2.  * Time_ToParts.c --
  3.  *
  4.  *    Source code for the Time_ToParts library procedure.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/lib/c/time/RCS/Time_ToParts.c,v 1.4 90/09/11 14:28:37 kupfer Exp $ SPRITE (Berkeley)";
  18. #endif not lint
  19.  
  20. #include <sprite.h>
  21. #include <spriteTime.h>
  22.  
  23. /* 
  24.  * Forward declarations:
  25.  */
  26. static int YearLength _ARGS_((int year));
  27.  
  28.  
  29. /* 
  30.  *----------------------------------------------------------------------
  31.  *
  32.  *  YearLength --
  33.  *
  34.  *  Result:
  35.  *    The number of days in the year.
  36.  *
  37.  *  Side effects:
  38.  *    None.
  39.  *
  40.  *----------------------------------------------------------------------
  41.  */
  42.  
  43. static int
  44. YearLength(year)
  45.     int year;
  46. {
  47.     if (year%400 == 0) {
  48.     return(366);
  49.     }
  50.     if (year%100 == 0) {
  51.     return(355);
  52.     }
  53.     if (year%4 == 0) {
  54.     return(366);
  55.     }
  56.     return(365);
  57. }
  58.  
  59. /*
  60.  *----------------------------------------------------------------------
  61.  *
  62.  *  Time_ToParts --
  63.  *
  64.  *    Converts a time value into its components.
  65.  *    If relative time is specified, the time is broken down to days,
  66.  *    hours, minutes and seconds only.
  67.  *
  68.  *    Modified from UNIX ctime.c -- NEEDS TO BE REWRITTEN!!
  69.  *
  70.  * Results:
  71.  *    None.
  72.  *
  73.  * Side effects:
  74.  *    None.
  75.  *
  76.  *----------------------------------------------------------------------
  77.  */
  78.  
  79. void
  80. Time_ToParts(time, relativeTime, partsPtr)
  81.     int     time;
  82.     Boolean     relativeTime;
  83.     register Time_Parts *partsPtr;
  84. {
  85.     int         hms, day;
  86.     int        dayOfMonth, month, year;
  87.     Boolean        negative;
  88.     static int     monthLengths[] = {
  89.         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  90.     static int     leapMonthLengths[] = {
  91.         31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  92.     int        *monthLenPtr;
  93.  
  94.     /*
  95.      * break initial number into days
  96.      */
  97.  
  98.     if (time < 0) {
  99.         negative = TRUE;
  100.         time = -time;
  101.     } else {
  102.         negative = FALSE;
  103.     }
  104.     hms = time % 86400;
  105.     day = time / 86400;
  106.     if (hms<0) {
  107.         hms += 86400;
  108.         day -= 1;
  109.     }
  110.  
  111.     /*
  112.      * generate hours:minutes:seconds
  113.      */
  114.     partsPtr->seconds     = hms % 60;
  115.     hms             /= 60;
  116.     partsPtr->minutes    = hms % 60;
  117.     partsPtr->hours     = hms / 60;
  118.  
  119.     /*
  120.      * For a relative time, determine days, hours, minutes and seconds only.
  121.      */
  122.  
  123.     if (relativeTime) {
  124.         if (negative) {
  125.         partsPtr->dayOfYear = -day;
  126.         } else {
  127.         partsPtr->dayOfYear = day;
  128.         }
  129.         return;
  130.     }
  131.  
  132.     /*
  133.      * day is the day number.
  134.      * generate day of the week.
  135.      * The addend is 4 mod 7 (1/1/1970 was Thursday)
  136.      */
  137.  
  138.     partsPtr->dayOfWeek = (day + 7340036) % 7;
  139.  
  140.     /*
  141.      * year number
  142.      */
  143.     if (day >= 0) {
  144.         for(year=70; day >= YearLength(year); year++) {
  145.         day -= YearLength(year);
  146.         }
  147.     } else {
  148.         for (year=70; day<0; year--) {
  149.         day += YearLength(year-1);
  150.         }
  151.     }
  152.     partsPtr->year         = year;
  153.     partsPtr->dayOfYear     = day;
  154.  
  155.     /*
  156.      * generate month
  157.      */
  158.  
  159.     if (YearLength(year)==366) {
  160.         monthLenPtr = leapMonthLengths;
  161.     } else {
  162.         monthLenPtr = monthLengths;
  163.     }
  164.     
  165.     for (dayOfMonth = day, month=0; 
  166.          dayOfMonth >= monthLenPtr[month]; 
  167.          month++) {
  168.         dayOfMonth -= monthLenPtr[month];
  169.     }
  170.     dayOfMonth += 1;
  171.     partsPtr->dayOfMonth     = dayOfMonth;
  172.     partsPtr->month     = month;
  173. }
  174.  
  175. /*
  176.  *----------------------------------------------------------------------
  177.  *
  178.  *  Time_FromParts --
  179.  *
  180.  *    Converts components of a time into a time value.
  181.  *    If relative time is specified, the time comprised of days,
  182.  *    hours, minutes and seconds only.
  183.  *
  184.  *    Modified from UNIX ctime.c -- NEEDS TO BE REWRITTEN!!
  185.  *      IMPORTANT: won't do dates before 1970!!!
  186.  *
  187.  * Results:
  188.  *    SUCCESS if time was converted, FAILURE otherwise.
  189.  *
  190.  * Side effects:
  191.  *    None.
  192.  *
  193.  *----------------------------------------------------------------------
  194.  */
  195.  
  196. ReturnStatus
  197. Time_FromParts(partsPtr,relativeTime, timePtr)
  198.     register Time_Parts *partsPtr;
  199.     Boolean     relativeTime;
  200.     int     *timePtr;
  201. {
  202.  
  203. #define CENTURY    1900
  204.  
  205.     int        month, year;
  206.     static int     monthLengths[] = {
  207.         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  208.     static int     leapMonthLengths[] = {
  209.         31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  210.     int        *monthLenPtr;
  211.     int         days;
  212.     int        seconds;
  213.     int        dayOfYear = 0;
  214.  
  215.     if  (partsPtr->year < 70) {
  216.     return FAILURE;
  217.     }
  218.     if ((partsPtr->dayOfMonth == -1) && (partsPtr->dayOfYear == -1)) {
  219.     return FAILURE;
  220.     }
  221.     days = 0;
  222.     if (!relativeTime) {
  223.     for (year = 1970; year < partsPtr->year + CENTURY; year++) {
  224.         days += YearLength(year);
  225.     } 
  226.     if (partsPtr->dayOfMonth != -1) {
  227.         if (YearLength(partsPtr->year + CENTURY) == 366) {
  228.         monthLenPtr = leapMonthLengths;
  229.         } else {
  230.         monthLenPtr = monthLengths;
  231.         }
  232.         for (month = 0; month < partsPtr->month; month++) {
  233.         dayOfYear += monthLenPtr[month];
  234.         }
  235.         dayOfYear += partsPtr->dayOfMonth - 1;
  236.         if (partsPtr->dayOfYear != -1) {
  237.         if (dayOfYear != partsPtr->dayOfYear) {
  238.             return FAILURE;
  239.         }
  240.         }
  241.     } else {
  242.         dayOfYear = partsPtr->dayOfYear;
  243.     }
  244.     }
  245.     days += dayOfYear;
  246.     seconds = days * (24 * 60 * 60);
  247.     seconds += partsPtr->hours * 60 * 60;
  248.     seconds += partsPtr->minutes * 60;
  249.     seconds += partsPtr->seconds;
  250.     *timePtr = seconds;
  251.     return SUCCESS;
  252. }
  253.